/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package x10.interfaces.cm15a.transmit;

import java.util.BitSet;
import java.util.logging.Logger;

import x10.enums.Device;
import x10.enums.Function;
import x10.enums.House;
import x10.event.X10Command;
import x10.event.X10Event;
import x10.queues.X10TransmitQueue;
import x10.utilities.BitSetUtils;
import x10.utilities.ChunkOfBytes;

/**
 *
 * @author Denny
 */
public class RFCommandFactory extends X10DeviceTransmitter{
    Logger logger = Logger.getLogger(this.getClass().getName());
    X10Command rfCommand;

    public RFCommandFactory(X10TransmitQueue transmitQueue){
        super(transmitQueue);
    }

    public void transmit(X10Event device){
        try{
            rfCommand = (X10Command)device;
        } catch (Exception e){
            logger.warning("Unable to cast X10Device to X10Command (RADIO_FREQUENCY)");
            e.printStackTrace();
        }

        ChunkOfBytes chunk = new ChunkOfBytes();
        byte[] addressBytes = getAddressAndFunctionBytes();

        byte[] bytes = new byte[6];
        bytes[0] = (byte) 0xEB;  //Transmit RF
        bytes[1] = (byte) 0x20;  //RF Command Header
        bytes[2] = addressBytes[0];
        bytes[3] = BitSetUtils.inverseByte(bytes[2]);
        bytes[4] = addressBytes[1];
        bytes[5] = BitSetUtils.inverseByte(bytes[4]);

        chunk.setBytes(bytes);
        chunk.setLength(6);
        chunk.setEmpty(false);

        transmitQueue.put(chunk);
    }

    public byte[] getAddressAndFunctionBytes(){
        byte[] bytes = new byte[2];
        BitSet bits = new BitSet();

        setHouseBits(bits);
        setDeviceBits(bits);
        setFunctionBits(bits);

        BitSetUtils.bitSetToBytes(bits, bytes);

        return bytes;
    }

    public void setHouseBits(BitSet bits){
        House house = rfCommand.getHouseCode();
        byte houseByte = house.getRadioFrequencyVersion();
        BitSet houseBits = BitSetUtils.byteToBitSet(houseByte);

        //Overlay houseBits 4 - 7 onto bits 0 - 3
        for(int x = 4; x < 8; x++){
            if(houseBits.get(x)){
                bits.set(x - 4);
            }
        }
    }

    public void setDeviceBits(BitSet bits){
        Device device = rfCommand.getDeviceCode();
        Function function = rfCommand.getFunctionCode();

        if (function.equals(Function.ON) || function.equals(Function.OFF)){
            byte deviceByte = device.getOrdinal();
            BitSet deviceBits = BitSetUtils.byteToBitSet(deviceByte);

            if(deviceBits.get(4)){
                bits.set(5);  //D8
            }
            if(deviceBits.get(5)){
                bits.set(9);  //D4
            }
            if(deviceBits.get(6)){
                bits.set(12);  //D2
            }
            if(deviceBits.get(7)){
                bits.set(11);  //D1
            }
            
        } else {
            //Do Nothing -- device number not needed if not using the above functions
        }

    }

    public void setFunctionBits(BitSet bits){
        Function function = rfCommand.getFunctionCode();
        
        if(function.equals(Function.ON)){
            //Do nothing
        } else if(function.equals(Function.OFF)){
            bits.set(10); //F1
        } else if(function.equals(Function.ALL_UNITS_OFF)){
            bits.set(8);  //F8
        } else if(function.equals(Function.ALL_LIGHTS_ON)){
            bits.set(8);  //F8
            bits.set(11); //F4
        } else if(function.equals(Function.BRIGHT)){
            bits.set(8);  //F8
            bits.set(12); //F2
        } else if(function.equals(Function.DIM)){
            bits.set(8);  //F8
            bits.set(11); //F4
            bits.set(12); //F2
        }
    }
}
